#!/bin/bash

# Docker容器完整导入脚本
# 功能：导入所有容器、镜像、卷和网络配置，智能处理网络冲突
# 版本: 1.0
# 使用方法: ./docker_import.sh [选项]

set -e

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

# 日志函数
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }

# 配置选项
INTERACTIVE_MODE=true
AUTO_RESOLVE_CONFLICTS=false
SKIP_NETWORK_RESTORE=false
FORCE_RECREATE_NETWORKS=false
NETWORK_PREFIX="migrated"
DRY_RUN=false
BIND_MOUNTS_BASE_DIR="/opt/docker_mounts"

# 显示帮助信息
show_help() {
    cat << EOF
Docker容器完整导入脚本

用法: $0 [选项]

功能:
  - 导入所有镜像
  - 智能处理网络冲突并创建网络
  - 导入所有卷数据
  - 重建容器并保持原有配置

选项:
  -h, --help              显示此帮助信息
  -i, --interactive       交互模式（默认）
  -a, --auto              自动解决冲突模式
  -s, --skip-networks     跳过网络还原
  -f, --force-recreate    强制重建网络
  -p, --prefix PREFIX     网络重命名前缀（默认: migrated）
  -b, --bind-base DIR     绑定挂载基础目录（默认: /opt/docker_mounts）
  --dry-run              仅显示将要执行的操作，不实际执行

示例:
  $0                      # 交互模式导入
  $0 -a                   # 自动模式导入
  $0 -b /data/mounts      # 指定绑定挂载基础目录
  $0 -a -b /opt/mounts    # 自动模式并指定挂载目录
  $0 -s                   # 跳过网络导入
  $0 --dry-run            # 预览模式
EOF
}

# 解析命令行参数
while [[ $# -gt 0 ]]; do
    case $1 in
        -h|--help)
            show_help
            exit 0
            ;;
        -i|--interactive)
            INTERACTIVE_MODE=true
            AUTO_RESOLVE_CONFLICTS=false
            shift
            ;;
        -a|--auto)
            INTERACTIVE_MODE=false
            AUTO_RESOLVE_CONFLICTS=true
            shift
            ;;
        -s|--skip-networks)
            SKIP_NETWORK_RESTORE=true
            shift
            ;;
        -f|--force-recreate)
            FORCE_RECREATE_NETWORKS=true
            shift
            ;;
        -p|--prefix)
            NETWORK_PREFIX="$2"
            shift 2
            ;;
        -b|--bind-base)
            BIND_MOUNTS_BASE_DIR="$2"
            shift 2
            ;;
        --dry-run)
            DRY_RUN=true
            shift
            ;;
        *)
            log_error "未知选项: $1"
            show_help
            exit 1
            ;;
    esac
done

# 执行命令（支持dry-run模式）
execute_command() {
    local cmd="$1"
    local description="$2"
    
    if [ "$DRY_RUN" = true ]; then
        log_info "[预览] $description"
        log_info "[预览] 将执行: $cmd"
        return 0
    else
        log_info "$description"
        eval "$cmd"
        return $?
    fi
}

# 检查Docker状态
check_docker() {
    if ! command -v docker >/dev/null 2>&1; then
        log_error "Docker未安装"
        exit 1
    fi
    
    if ! docker info >/dev/null 2>&1; then
        log_error "Docker未运行或权限不足"
        exit 1
    fi
    
    log_success "Docker状态正常"
}

# 检查依赖工具
check_dependencies() {
    local missing_tools=()
    
    for tool in jq tar gzip; do
        if ! command -v "$tool" >/dev/null 2>&1; then
            missing_tools+=("$tool")
        fi
    done
    
    if [ ${#missing_tools[@]} -gt 0 ]; then
        log_error "缺少必要工具: ${missing_tools[*]}"
        log_info "请安装缺少的工具后重试"
        exit 1
    fi
    
    log_success "所有依赖工具已安装"
}

# 检查导出数据
check_export_data() {
    if [ ! -d "images" ] && [ ! -d "volumes" ] && [ ! -d "networks" ] && [ ! -d "configs" ]; then
        log_error "未找到导出的数据目录，请确保在正确的目录中运行此脚本"
        log_info "目录应包含: images/, volumes/, networks/, configs/"
        exit 1
    fi
    
    if [ ! -f "container_mapping.csv" ]; then
        log_error "未找到容器映射文件 container_mapping.csv"
        exit 1
    fi
    
    log_success "导出数据检查完成"
}

# 检查子网冲突
check_subnet_conflict() {
    local subnet="$1"
    local conflicted_networks=()
    
    while IFS= read -r network_name; do
        if [ "$network_name" != "" ]; then
            existing_subnet=$(docker network inspect "$network_name" 2>/dev/null | jq -r '.[0].IPAM.Config[0].Subnet // empty' 2>/dev/null || echo "")
            if [ "$existing_subnet" = "$subnet" ]; then
                conflicted_networks+=("$network_name")
            fi
        fi
    done < <(docker network ls --format "{{.Name}}")
    
    if [ ${#conflicted_networks[@]} -gt 0 ]; then
        log_warning "子网 $subnet 与以下网络冲突: ${conflicted_networks[*]}"
        return 0  # 有冲突
    fi
    
    return 1  # 无冲突
}

# 寻找可用子网
find_available_subnet() {
    local base_subnet="$1"
    local subnet_type="16"  # 默认/16
    
    # 检测子网类型
    if [[ "$base_subnet" == *"/24" ]]; then
        subnet_type="24"
    fi
    
    # 尝试172.x.0.0/16段
    for i in {20..254}; do
        if [ "$subnet_type" = "16" ]; then
            candidate="172.$i.0.0/16"
        else
            candidate="172.20.$i.0/24"
        fi
        
        if ! check_subnet_conflict "$candidate"; then
            echo "$candidate"
            return 0
        fi
    done
    
    # 尝试10.x.0.0/16段
    for i in {10..99}; do
        if [ "$subnet_type" = "16" ]; then
            candidate="10.$i.0.0/16"
        else
            candidate="10.0.$i.0/24"
        fi
        
        if ! check_subnet_conflict "$candidate"; then
            echo "$candidate"
            return 0
        fi
    done
    
    # 尝试192.168.x.0/24段
    for i in {100..200}; do
        candidate="192.168.$i.0/24"
        if ! check_subnet_conflict "$candidate"; then
            echo "$candidate"
            return 0
        fi
    done
    
    log_error "无法找到可用的子网段"
    return 1
}

# 计算网关地址
calculate_gateway() {
    local subnet="$1"
    
    if [[ "$subnet" == */16 ]]; then
        echo "${subnet%.*}.0.1"
    elif [[ "$subnet" == */24 ]]; then
        echo "${subnet%.*}.1"
    else
        # 默认处理
        echo "${subnet%.*}.1"
    fi
}

# 导入镜像
import_images() {
    log_info "开始导入镜像..."
    
    if [ ! -d "images" ]; then
        log_warning "未找到镜像目录，跳过镜像导入"
        return 0
    fi
    
    local failed_images=()
    local success_count=0
    
    for image_file in images/*.tar; do
        if [ -f "$image_file" ]; then
            local image_name=$(basename "$image_file")
            log_info "导入镜像: $image_name"
            
            if [ "$DRY_RUN" = true ]; then
                log_info "[预览] 加载镜像: $image_name"
                log_info "[预览] 将执行: docker load < $image_file"
                continue
            fi
            
            # 检查文件完整性
            if ! tar -tf "$image_file" >/dev/null 2>&1; then
                log_error "镜像文件 $image_name 损坏，跳过"
                failed_images+=("$image_name (文件损坏)")
                continue
            fi
            
            log_info "加载镜像: $image_name"
            
            # 尝试加载镜像，最多重试3次
            local retry_count=0
            local max_retries=3
            local load_success=false
            
            while [ $retry_count -lt $max_retries ] && [ "$load_success" = false ]; do
                if [ $retry_count -gt 0 ]; then
                    log_info "重试加载镜像 $image_name (第 $((retry_count + 1)) 次尝试)"
                    sleep 3
                fi
                
                # 尝试加载镜像并捕获详细错误信息
                local load_output
                load_output=$(docker load < "$image_file" 2>&1)
                local load_exit_code=$?
                
                if [ $load_exit_code -eq 0 ]; then
                    log_success "镜像 $image_name 加载成功"
                    if [ -n "$load_output" ]; then
                        log_info "加载输出: $load_output"
                    fi
                    load_success=true
                    ((success_count++))
                else
                    ((retry_count++))
                    log_warning "镜像 $image_name 加载失败: $load_output"
                    
                    # 检查是否是特定的错误类型
                    if echo "$load_output" | grep -q "repositories: no such file or directory"; then
                        log_info "检测到repositories文件缺失错误，尝试清理Docker临时目录..."
                        # 清理可能的临时文件
                        docker system prune -f >/dev/null 2>&1 || true
                        sleep 2
                    elif echo "$load_output" | grep -q "unexpected EOF"; then
                        log_info "检测到文件截断错误，检查文件完整性..."
                        if ! tar -tf "$image_file" >/dev/null 2>&1; then
                            log_error "镜像文件 $image_name 已损坏，跳过重试"
                            break
                        fi
                    fi
                    
                    if [ $retry_count -lt $max_retries ]; then
                        log_warning "准备重试..."
                    fi
                fi
            done
            
            if [ "$load_success" = false ]; then
                log_error "镜像 $image_name 加载失败（已重试 $max_retries 次）"
                failed_images+=("$image_name")
            fi
        fi
    done
    
    # 输出导入结果统计
    local total_images=$(ls images/*.tar 2>/dev/null | wc -l)
    log_info "镜像导入统计: 成功 $success_count/$total_images"
    
    if [ ${#failed_images[@]} -gt 0 ]; then
        log_warning "以下镜像导入失败:"
        for failed_image in "${failed_images[@]}"; do
            log_warning "  - $failed_image"
        done
        log_info "提示: 可以稍后手动导入失败的镜像: docker load < images/镜像名.tar"
    fi
    
    log_success "镜像导入完成"
}

# 智能导入网络
import_networks() {
    if [ "$SKIP_NETWORK_RESTORE" = true ]; then
        log_info "跳过网络导入（用户指定）"
        return 0
    fi
    
    if [ ! -d "networks" ]; then
        log_warning "未找到网络目录，跳过网络导入"
        return 0
    fi
    
    log_info "开始智能网络导入..."
    
    # 创建网络映射文件
    echo "original_name,new_name,original_subnet,new_subnet" > network_mapping.csv
    
    for network_file in networks/*.json; do
        if [ ! -f "$network_file" ]; then
            continue
        fi
        
        original_network_name=$(basename "$network_file" .json)
        network_name="$original_network_name"
        
        log_info "处理网络: $original_network_name"
        
        # 检查网络是否已存在
        if docker network ls --format "{{.Name}}" | grep -q "^${network_name}$"; then
            log_warning "网络 $network_name 已存在"
            
            if [ "$FORCE_RECREATE_NETWORKS" = true ]; then
                log_info "强制删除现有网络"
                execute_command "docker network rm $network_name" "删除现有网络 $network_name"
            elif [ "$INTERACTIVE_MODE" = true ]; then
                echo
                echo "网络处理选项:"
                echo "1) 跳过此网络"
                echo "2) 重命名并创建新网络"
                echo "3) 删除现有网络并重建"
                read -p "请选择 (1-3): " -n 1 -r choice
                echo
                
                case $choice in
                    1)
                        log_info "跳过网络 $network_name"
                        continue
                        ;;
                    2)
                        network_name="${NETWORK_PREFIX}_${original_network_name}_$(date +%s)"
                        log_info "重命名为: $network_name"
                        ;;
                    3)
                        execute_command "docker network rm $network_name" "删除现有网络 $network_name"
                        ;;
                    *)
                        log_info "无效选择，跳过此网络"
                        continue
                        ;;
                esac
            elif [ "$AUTO_RESOLVE_CONFLICTS" = true ]; then
                network_name="${NETWORK_PREFIX}_${original_network_name}_$(date +%s)"
                log_info "自动重命名为: $network_name"
            else
                log_info "跳过网络 $network_name"
                continue
            fi
        fi
        
        # 提取网络配置
        driver=$(jq -r '.[0].Driver' "$network_file" 2>/dev/null || echo "bridge")
        original_subnet=$(jq -r '.[0].IPAM.Config[0].Subnet // empty' "$network_file" 2>/dev/null || echo "")
        original_gateway=$(jq -r '.[0].IPAM.Config[0].Gateway // empty' "$network_file" 2>/dev/null || echo "")
        
        new_subnet="$original_subnet"
        new_gateway="$original_gateway"
        
        # 处理子网冲突
        if [ "$original_subnet" != "" ] && [ "$original_subnet" != "null" ]; then
            if check_subnet_conflict "$original_subnet"; then
                log_warning "子网 $original_subnet 存在冲突"
                
                if [ "$INTERACTIVE_MODE" = true ]; then
                    echo
                    echo "子网冲突处理选项:"
                    echo "1) 自动分配新子网"
                    echo "2) 让Docker自动管理（不指定子网）"
                    echo "3) 手动输入新子网"
                    read -p "请选择 (1-3): " -n 1 -r subnet_choice
                    echo
                    
                    case $subnet_choice in
                        1)
                            new_subnet=$(find_available_subnet "$original_subnet")
                            if [ $? -eq 0 ]; then
                                new_gateway=$(calculate_gateway "$new_subnet")
                                log_info "自动分配子网: $new_subnet, 网关: $new_gateway"
                            else
                                log_error "无法找到可用子网，将让Docker自动管理"
                                new_subnet=""
                                new_gateway=""
                            fi
                            ;;
                        2)
                            new_subnet=""
                            new_gateway=""
                            log_info "将让Docker自动管理网络"
                            ;;
                        3)
                            read -p "请输入新的子网 (例如: 172.30.0.0/16): " new_subnet
                            if [ "$new_subnet" != "" ]; then
                                new_gateway=$(calculate_gateway "$new_subnet")
                                log_info "使用手动指定的子网: $new_subnet, 网关: $new_gateway"
                            fi
                            ;;
                        *)
                            log_info "无效选择，让Docker自动管理"
                            new_subnet=""
                            new_gateway=""
                            ;;
                    esac
                elif [ "$AUTO_RESOLVE_CONFLICTS" = true ]; then
                    new_subnet=$(find_available_subnet "$original_subnet")
                    if [ $? -eq 0 ]; then
                        new_gateway=$(calculate_gateway "$new_subnet")
                        log_info "自动分配新子网: $new_subnet, 网关: $new_gateway"
                    else
                        log_warning "无法找到可用子网，让Docker自动管理"
                        new_subnet=""
                        new_gateway=""
                    fi
                fi
            else
                log_success "子网 $original_subnet 无冲突，直接使用"
            fi
        else
            log_info "原网络未指定子网，让Docker自动管理"
        fi
        
        # 构建网络创建命令
        create_cmd="docker network create --driver $driver"
        
        if [ "$new_subnet" != "" ] && [ "$new_subnet" != "null" ]; then
            create_cmd="$create_cmd --subnet=$new_subnet"
        fi
        
        if [ "$new_gateway" != "" ] && [ "$new_gateway" != "null" ]; then
            create_cmd="$create_cmd --gateway=$new_gateway"
        fi
        
        create_cmd="$create_cmd $network_name"
        
        # 执行网络创建
        if execute_command "$create_cmd" "创建网络 $network_name"; then
            log_success "网络 $network_name 创建完成"
            
            # 记录网络映射
            echo "$original_network_name,$network_name,$original_subnet,$new_subnet" >> network_mapping.csv
        else
            log_error "网络 $network_name 创建失败"
        fi
        
        echo  # 添加空行分隔
    done
    
    log_success "网络导入完成"
}

# 导入卷
import_volumes() {
    log_info "开始导入卷..."
    
    if [ ! -d "volumes" ]; then
        log_warning "未找到卷目录，跳过卷导入"
        return 0
    fi
    
    for volume_file in volumes/*.tar.gz; do
        if [ -f "$volume_file" ]; then
            volume_name=$(basename "$volume_file" .tar.gz)
            
            log_info "导入卷: $volume_name"
            
            # 检查卷是否已存在
            if docker volume ls --format "{{.Name}}" | grep -q "^${volume_name}$"; then
                log_warning "卷 $volume_name 已存在，跳过创建"
                continue
            fi
            
            execute_command "docker volume create '$volume_name'" "创建卷: $volume_name"
            
            if [ "$DRY_RUN" = false ]; then
                # 还原卷数据 - 使用重试机制
                log_info "还原卷数据: $volume_name"
                
                local restore_success=false
                local retry_count=0
                local max_retries=3
                
                while [ $retry_count -lt $max_retries ] && [ "$restore_success" = false ]; do
                    if [ $retry_count -gt 0 ]; then
                        log_info "重试还原卷数据 $volume_name (第 $((retry_count + 1)) 次尝试)"
                        sleep 5
                    fi
                    
                    # 尝试使用alpine镜像还原数据
                    if docker run --rm -v "$volume_name:/volume_data" -v "$(pwd)/volumes:/backup" alpine:latest tar xzf "/backup/${volume_name}.tar.gz" -C /volume_data 2>/dev/null; then
                        log_success "卷 $volume_name 数据还原成功"
                        restore_success=true
                    else
                        ((retry_count++))
                        if [ $retry_count -lt $max_retries ]; then
                            log_warning "卷 $volume_name 数据还原失败，准备重试..."
                        fi
                    fi
                done
                
                if [ "$restore_success" = false ]; then
                    log_error "卷 $volume_name 数据还原失败（已重试 $max_retries 次）"
                    log_info "尝试使用其他镜像进行还原..."
                    
                    # 尝试使用其他可用的小镜像
                    for fallback_image in "redis:7-alpine" "nginx:latest"; do
                        if docker images --format "{{.Repository}}:{{.Tag}}" | grep -q "^$fallback_image$"; then
                            log_info "使用备用镜像 $fallback_image 还原卷数据"
                            if docker run --rm -v "$volume_name:/volume_data" -v "$(pwd)/volumes:/backup" "$fallback_image" tar xzf "/backup/${volume_name}.tar.gz" -C /volume_data 2>/dev/null; then
                                log_success "使用备用镜像 $fallback_image 成功还原卷 $volume_name"
                                restore_success=true
                                break
                            fi
                        fi
                    done
                    
                    if [ "$restore_success" = false ]; then
                        log_error "所有还原方法都失败，卷 $volume_name 数据未能还原"
                    fi
                fi
            fi
        fi
    done
    
    log_success "卷导入完成"
}

# 导入绑定挂载文件
import_bind_mounts() {
    log_info "开始导入绑定挂载文件..."
    
    if [ ! -d "bind_mounts" ]; then
        log_info "未找到绑定挂载目录，跳过绑定挂载导入"
        return 0
    fi
    
    if [ ! -f "bind_mounts_mapping.csv" ]; then
        log_info "未找到绑定挂载映射文件，跳过绑定挂载导入"
        return 0
    fi
    
    log_info "绑定挂载基础目录: $BIND_MOUNTS_BASE_DIR"
    
    # 读取绑定挂载映射文件
    while IFS=',' read -r container_name source_path destination_path; do
        # 跳过标题行
        if [ "$container_name" = "container_name" ]; then
            continue
        fi
        
        log_info "恢复绑定挂载: $source_path -> $destination_path"
        
        # 构建新的源路径（基于绑定挂载基础目录）
        new_source_path="$BIND_MOUNTS_BASE_DIR/$source_path"
        
        # 创建新的源路径目录
        new_source_dir=$(dirname "$new_source_path")
        if [ ! -d "$new_source_dir" ]; then
            if execute_command "mkdir -p '$new_source_dir'" "创建目录 $new_source_dir"; then
                log_success "目录 $new_source_dir 创建完成"
            else
                log_error "目录 $new_source_dir 创建失败"
                continue
            fi
        fi
        
        # 构建导出文件路径（基于新的服务名称目录结构）
        exported_file="bind_mounts/$source_path"
        
        if [ -e "$exported_file" ]; then
            if [ -d "$exported_file" ]; then
                # 复制目录
                if execute_command "cp -r '$exported_file'/* '$new_source_path/' 2>/dev/null || cp -r '$exported_file' '$new_source_dir/'" "恢复目录 $source_path"; then
                    log_success "目录 $source_path 恢复到 $new_source_path"
                else
                    log_error "目录 $source_path 恢复失败"
                fi
            elif [ -f "$exported_file" ]; then
                # 复制文件
                if execute_command "cp '$exported_file' '$new_source_path'" "恢复文件 $source_path"; then
                    log_success "文件 $source_path 恢复到 $new_source_path"
                else
                    log_error "文件 $source_path 恢复失败"
                fi
            fi
        else
            log_warning "绑定挂载源文件不存在: $exported_file"
        fi
    done < "bind_mounts_mapping.csv"
    
    log_success "绑定挂载导入完成"
}

# 获取新的网络名称
get_new_network_name() {
    local original_name="$1"
    
    if [ -f "network_mapping.csv" ]; then
        # 跳过标题行，查找映射
        new_name=$(tail -n +2 network_mapping.csv | grep "^$original_name," | cut -d',' -f2)
        if [ "$new_name" != "" ]; then
            echo "$new_name"
            return 0
        fi
    fi
    
    # 如果没有找到映射，返回原名称
    echo "$original_name"
}

# 导入容器
import_containers() {
    log_info "开始导入容器..."
    
    if [ ! -f "container_mapping.csv" ]; then
        log_error "找不到容器映射文件 container_mapping.csv"
        return 1
    fi
    
    while IFS=',' read -r container_id container_name image_name safe_image_name; do
        # 跳过标题行
        if [ "$container_id" = "container_id" ]; then
            continue
        fi
        
        log_info "导入容器: $container_name"
        
        # 读取容器配置
        config_file="configs/${container_name}_inspect.json"
        
        if [ ! -f "$config_file" ]; then
            log_error "找不到容器 $container_name 的配置文件"
            continue
        fi
        
        # 提取运行参数 - 正确处理数组参数
        cmd=$(jq -r '.[0].Args // [] | map("\"" + . + "\"") | join(" ")' "$config_file" 2>/dev/null || echo "")
        entrypoint=$(jq -r '.[0].Config.Entrypoint // [] | join(" ")' "$config_file" 2>/dev/null || echo "")
        
        # 过滤环境变量
        env_vars=$(jq -r '.[0].Config.Env[]? | select(. | startswith("PATH=") | not) | select(. | startswith("HOME=") | not) | select(. | startswith("HOSTNAME=") | not)' "$config_file" 2>/dev/null | sed 's/^/-e /' | tr '\n' ' ' || echo "")
        
        # 提取端口映射
        ports=$(jq -r '.[0].HostConfig.PortBindings | to_entries[]? | "-p " + .value[0].HostPort + ":" + .key' "$config_file" 2>/dev/null | tr '\n' ' ' || echo "")
        
        # 提取卷挂载
        volumes=""
        while IFS= read -r mount_info; do
            mount_type=$(echo "$mount_info" | jq -r '.Type')
            if [ "$mount_type" = "volume" ]; then
                # 卷挂载
                volume_name=$(echo "$mount_info" | jq -r '.Name')
                destination=$(echo "$mount_info" | jq -r '.Destination')
                volumes="$volumes -v $volume_name:$destination"
            elif [ "$mount_type" = "bind" ]; then
                # 绑定挂载 - 使用新的基础目录路径
                original_source=$(echo "$mount_info" | jq -r '.Source')
                destination=$(echo "$mount_info" | jq -r '.Destination')
                mode=$(echo "$mount_info" | jq -r '.Mode // "rw"')
                
                # 从bind_mounts_mapping.csv中查找对应的相对路径
                if [ -f "bind_mounts_mapping.csv" ]; then
                    relative_path=$(grep ",$destination$" bind_mounts_mapping.csv | cut -d',' -f2 | head -1)
                    if [ -n "$relative_path" ]; then
                        new_source_path="$BIND_MOUNTS_BASE_DIR/$relative_path"
                        if [ -e "$new_source_path" ]; then
                            volumes="$volumes -v $new_source_path:$destination:$mode"
                            log_info "绑定挂载: $new_source_path -> $destination"
                        else
                            log_warning "跳过绑定挂载 $new_source_path -> $destination (新路径不存在)"
                        fi
                    else
                        log_warning "未找到绑定挂载映射: $destination"
                    fi
                else
                    # 如果没有映射文件，尝试使用原路径
                    if [ -e "$original_source" ]; then
                        volumes="$volumes -v $original_source:$destination:$mode"
                        log_info "绑定挂载: $original_source -> $destination"
                    else
                        log_warning "跳过绑定挂载 $original_source -> $destination (源路径不存在)"
                    fi
                fi
            fi
        done < <(jq -c '.[0].Mounts[]?' "$config_file" 2>/dev/null || echo "")
        
        # 提取网络（获取第一个网络用于创建）
        first_network=$(jq -r '.[0].NetworkSettings.Networks | keys[0]?' "$config_file" 2>/dev/null || echo "")
        all_networks=$(jq -r '.[0].NetworkSettings.Networks | keys[]?' "$config_file" 2>/dev/null || echo "")
        
        # 处理网络配置
        if [ "$SKIP_NETWORK_RESTORE" = true ]; then
            # 跳过网络导入时，创建一个临时网络以保持服务发现功能
            temp_network="imported_services"
            if ! docker network ls --format "{{.Name}}" | grep -q "^${temp_network}$"; then
                log_info "创建临时网络 $temp_network 以保持服务发现功能"
                execute_command "docker network create $temp_network" "创建临时网络"
            fi
            first_network="$temp_network"
        else
            # 获取新的网络名称
            if [ "$first_network" != "" ]; then
                first_network=$(get_new_network_name "$first_network")
            fi
        fi
        
        # 构建docker run命令
        run_cmd="docker run -d --name $container_name"
        
        if [ "$env_vars" != "" ]; then
            run_cmd="$run_cmd $env_vars"
        fi
        
        if [ "$ports" != "" ]; then
            run_cmd="$run_cmd $ports"
        fi
        
        if [ "$volumes" != "" ]; then
            run_cmd="$run_cmd $volumes"
        fi
        
        if [ "$first_network" != "" ] && [ "$first_network" != "null" ] && [ "$first_network" != "bridge" ]; then
            run_cmd="$run_cmd --network=$first_network"
        fi
        
        if [ "$entrypoint" != "" ] && [ "$entrypoint" != "null" ]; then
            run_cmd="$run_cmd --entrypoint $entrypoint"
        fi
        
        run_cmd="$run_cmd $image_name"
        
        if [ "$cmd" != "" ] && [ "$cmd" != "null" ]; then
            run_cmd="$run_cmd $cmd"
        fi
        
        # 执行容器创建
        if execute_command "$run_cmd" "创建容器: $container_name"; then
            log_success "容器 $container_name 创建完成"
            
            # 连接到其他网络
            if [ "$DRY_RUN" = false ] && [ "$SKIP_NETWORK_RESTORE" = false ]; then
                echo "$all_networks" | while read -r network; do
                    if [ "$network" != "" ] && [ "$network" != "$first_network" ]; then
                        new_network=$(get_new_network_name "$network")
                        if docker network ls --format "{{.Name}}" | grep -q "^${new_network}$"; then
                            execute_command "docker network connect '$new_network' '$container_name'" "连接容器到网络: $new_network"
                        else
                            log_warning "网络 $new_network 不存在，跳过连接"
                        fi
                    fi
                done
            elif [ "$SKIP_NETWORK_RESTORE" = true ] && [ "$DRY_RUN" = false ]; then
                # 在跳过网络导入模式下，为容器添加网络别名以保持服务发现功能
                log_info "为容器添加网络别名以保持服务发现功能"
                
                # 从原始网络配置中提取别名
                network_aliases=$(jq -r '.[0].NetworkSettings.Networks | to_entries[0].value.Aliases[]?' "$config_file" 2>/dev/null | grep -v "^${container_name}$" | head -5 || echo "")
                
                if [ "$network_aliases" != "" ]; then
                     # 先断开容器与临时网络的连接
                      execute_command "docker network disconnect '$temp_network' '$container_name'" "断开临时网络连接"
                      
                      # 构建别名参数
                      alias_args=""
                      while read -r alias; do
                          if [ "$alias" != "" ] && [ "$alias" != "$container_name" ]; then
                              alias_args="$alias_args --alias '$alias'"
                          fi
                      done <<< "$network_aliases"
                      
                      # 重新连接并添加所有别名
                      if [ "$alias_args" != "" ]; then
                          execute_command "docker network connect $alias_args '$temp_network' '$container_name'" "重新连接网络并添加别名"
                      else
                          execute_command "docker network connect '$temp_network' '$container_name'" "重新连接网络"
                      fi
                 else
                     log_info "未找到网络别名，保持当前网络连接"
                 fi
            fi
        else
            log_error "容器 $container_name 创建失败"
        fi
        
        echo  # 添加空行分隔
    done < container_mapping.csv
    
    log_success "容器导入完成"
}

# 验证导入结果
verify_import() {
    log_info "验证导入结果..."
    
    echo
    echo "=== 网络状态 ==="
    docker network ls
    
    echo
    echo "=== 卷状态 ==="
    docker volume ls
    
    echo
    echo "=== 容器状态 ==="
    docker ps -a
    
    echo
    echo "=== 镜像状态 ==="
    docker images
    
    if [ -f "network_mapping.csv" ]; then
        echo
        echo "=== 网络映射 ==="
        cat network_mapping.csv
    fi
    
    log_success "验证完成"
}

# 主函数
main() {
    echo "Docker容器完整导入脚本"
    echo "========================"
    echo
    
    if [ "$DRY_RUN" = true ]; then
        log_info "运行在预览模式，不会实际执行操作"
        echo
    fi
    
    # 检查环境
    check_docker
    check_dependencies
    check_export_data
    echo
    
    log_info "开始导入过程..."
    echo
    
    # 导入镜像
    import_images
    echo
    
    # 智能导入网络
    if [ "$SKIP_NETWORK_RESTORE" = false ]; then
        import_networks
    else
        log_info "跳过网络导入（--skip-networks选项已启用）"
    fi
    echo
    
    # 导入卷
    import_volumes
    echo
    
    # 导入绑定挂载文件
    import_bind_mounts
    echo
    
    # 导入容器
    import_containers
    echo
    
    # 验证结果
    if [ "$DRY_RUN" = false ]; then
        verify_import
    fi
    
    echo
    log_success "导入过程完成！"
    
    if [ -f "network_mapping.csv" ]; then
        echo
        log_info "网络映射信息已保存到 network_mapping.csv"
        log_info "如果遇到网络连接问题，请参考此文件进行故障排除"
    fi
    
    echo
    log_info "建议执行以下命令验证服务状态："
    echo "  docker ps                    # 检查容器状态"
    echo "  docker logs <container_name> # 检查容器日志"
    echo "  docker network inspect <network_name> # 检查网络详情"
}

# 运行主函数
main "$@"